/**
 * Classe que abstrai a agenda mensal do médico
 * Gera o HTML da Agenda para exibição em um JSP
 * @author Wendell Costa
 */

package sao.visao;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class AgendaMensal {
	
	//O dia da semana em que cai o primeiro dia do mês, sendo 1 = domingo, etc.
	private int primeiroDiaMesNaSemana;
	
	// O ano da agenda exibida (ex. 2010)
	private int ano;
	
	// O mês da agenda exibida, sendo 0 = janeiro
	private int mes;
	
	// O último dia do mês (ex. 31) 
	private int ultimoDiaMes;
	
	// Hoje (dia do mês)
	private int hoje;
	
	// Mês atual
	private int mesHoje;
	
	// Ano atual
	private int anoHoje;
	
	// Nome do mês atual
	private String nomeMesAtual;
	
	// Nome do mês seguinte
	private String nomeMesSeguinte;
	
	// Nome do mês anteior
	private String nomeMesAnterior;
	
	// Código do mês seguinte (janeiro = 0)
	private int codMesSeguinte;
	
	// Código do mês anterior (janeiro = 0)
	private int codMesAnterior;
	
	// Código do ano segunite
	private int anoSeguinte;
	
	// Código do ano anterior
	private int anoAnterior;
	
	// Código HTML com o link para o mês seguinte
	private String linkMesSeguinte;
	
	// Código HTML com o link para o mês anterior
	private String linkMesAnterior;
	
	
	
	/**
	 * Inicializa o código da agenda mensal recebendo o ano e o mês, sendo que o mês
	 * será recebido considerando janeiro = 1
	 * @param umMes - Inteiro representando o mês da agenda
	 * @param umAno - Inteiro representando o ano da agenda
	 */
	public AgendaMensal(int umMes, int umAno) {
		hoje = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);// Captura o dia de hoje
		mesHoje = Calendar.getInstance().get(Calendar.MONTH);// Captura o mês de hoje (0=janeiro)
		anoHoje = Calendar.getInstance().get(Calendar.YEAR);// Captura o ano de hoje
		ano = umAno;
		mes = umMes - 1;// Subtrai 1, pois o mês é recebido considerando janeiro = 1, e o construtor de Calendar
						// recebe o mês, considerando janeiro = 0
		Calendar cal = new GregorianCalendar(ano, mes, 1);
		ultimoDiaMes = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		primeiroDiaMesNaSemana = cal.get(Calendar.DAY_OF_WEEK);
		
		// Seta as variáveis auxiliares para gerar o HTML de navegação
		setVariaveisAuxiliares(cal);
		setLinkMesSeguinte();
		setLinkMesAnterior();
	}//FIM construtor
	
	
	/**
	 * @return String contendo o nome do mês atual
	 */
	public String getNomeMesAtual() {
		return nomeMesAtual;
	}
	
	
	/**
	 * @return Inteiro representando o ano da agenda
	 */
	public int getAno() {
		return ano;
	}


	/**
	 * @return String com o HTML para o link do mês seguinte ao da agenda
	 */
	public String getLinkMesSeguinte() {
		return linkMesSeguinte;
	}


	/**
	 * @return the String com o HTML para o link do mês anterior ao da agenda
	 */
	public String getLinkMesAnterior() {
		return linkMesAnterior;
	}


	/**
	 * Gera o HTML para o link da agenda para o mês anterior 
	 */
	private void setLinkMesAnterior() {
		this.linkMesAnterior = "<a href='agendarConsultaPropria.do?mes=" 
			+ codMesAnterior + "&ano=" + anoAnterior + "'>" + nomeMesAnterior + "/" 
			+ anoAnterior + "</a>";
	}


	/**
	 * Gera o HTML para o link da agenda para o mês seguinte
	 */
	private void setLinkMesSeguinte() {
		this.linkMesSeguinte = "<a href='agendarConsultaPropria.do?mes=" 
			+ codMesSeguinte + "&ano=" + anoSeguinte + "'>" + nomeMesSeguinte + "/" 
			+ anoSeguinte + "</a>";
	}


	/**
	 * Seta as variáveis auxiliares que serão usadas para criar os links de navegação
	 * da agenda
	 * @param cal - Objeto Calendar com a data do mês-ano corrente do calendário
	 */
	private void setVariaveisAuxiliares(Calendar cal) {
		Calendar calSeguinte = (Calendar) cal.clone();
		Calendar calAnterior = (Calendar) cal.clone();
		calSeguinte.add(Calendar.MONTH, 1);// Adiciona 1 ao mês atual
		calAnterior.add(Calendar.MONTH, -1);// Subtrai 1 do mês atual
		SimpleDateFormat fMesExtenso = new SimpleDateFormat("MMMM");// Mês por extenso
		SimpleDateFormat fMesCodigo = new SimpleDateFormat("MM");// Mês por código, Ex. 01 = Janeiro (CUIDADO!)
		SimpleDateFormat fAno = new SimpleDateFormat("yyyy");// Ano com 4 dígitos
		this.nomeMesAtual = fMesExtenso.format(cal.getTime());
		this.nomeMesSeguinte = fMesExtenso.format(calSeguinte.getTime());
		this.nomeMesAnterior = fMesExtenso.format(calAnterior.getTime());
		this.codMesSeguinte = Integer.parseInt(fMesCodigo.format(calSeguinte.getTime()));
		this.codMesAnterior = Integer.parseInt(fMesCodigo.format(calAnterior.getTime()));
		this.anoSeguinte = Integer.parseInt(fAno.format(calSeguinte.getTime()));
		this.anoAnterior = Integer.parseInt(fAno.format(calAnterior.getTime()));
	}


	/**
	 * Gera o código HMTL para a agenda conforme os parâmetros passados
	 * @return String com o código HTML da agenda
	 */
	public String getHTMLAgenda() {
		StringBuilder html = new StringBuilder();
		int dia = 1;
		
		// Linha de título
		html.append("<table><tr><th>DOM</th><th>SEG</th><th>TER</th>" 
				+ "<th>QUA</th><th>QUI</th><th>SEX</th><th>SAB</th></tr>\n");
		
		// Primeira semana
		html.append("<tr>\n");
		for (int i = 1; i <= 7; i++) {
			if (i < primeiroDiaMesNaSemana) {
				html.append("<td>&nbsp;</td>\n");
			} else {
				/*
				 * Teste para publicação do link
				 * Se o ano da agenda for maior que o ano de hoje > publica link
				 * Se o ano da agenda for o ano corrente e o mês for maior que o mês atual > publica link
				 * Se o ano for o corrente, o mês também e o dia maior igual ao dia de hoje > publica link
				 */
				if (ano>anoHoje || (ano>=anoHoje && mes>mesHoje) || (ano>=anoHoje && mes>=mesHoje && dia>=hoje)){
					html.append("\t<td><a href='exibeAgendaDia?ano=" + ano + "&mes=" 
							+ (mes+1) + "&dia=" + dia + "'>" + dia + "</a></td>\n");
				} else {// caso contrário, exibe apenas o dia
					html.append("\t<td>" + dia + "</td>\n");
				}
				dia++;
			}
		}
		html.append("</tr>\n");
		
		// Semanas restantes
		boolean existeSemanaCheia = true; // Rastreia se ainda existem semanas cheias
		while (existeSemanaCheia) {
			html.append("<tr>\n");
			for (int i = 1; i <= 7; i++) {
				if (ano>anoHoje || (ano>=anoHoje && mes>mesHoje) || (ano>=anoHoje && mes>=mesHoje && dia>=hoje)) {// se o dia for maior ou igual a hoje, exibe o link
					html.append("\t<td><a href='exibeAgendaDia?ano=" + ano + "&mes=" 
							+ (mes+1) + "&dia=" + dia + "'>" + dia + "</a></td>\n");
				} else {// caso contrário, exibe apenas o dia
					html.append("\t<td>" + dia + "</td>\n");
				}
				dia++;
			}
			html.append("</tr>\n");
			existeSemanaCheia = (ultimoDiaMes - dia >= 7) ? true : false;
		}
		
		// Última semana (caso haja semana quebrada)
		// Testa se ainda existem dias a serem exibidos
		boolean aindaExistemDias = dia <= ultimoDiaMes;
		if(aindaExistemDias){
			html.append("<tr>\n");
			for (int i = 1; i <= 7; i++) {
				if (aindaExistemDias) {
					if (ano>anoHoje || (ano>=anoHoje && mes>mesHoje) || (ano>=anoHoje && mes>=mesHoje && dia>=hoje)) {// se o dia for maior ou igual a hoje, exibe o link
						html.append("\t<td><a href='exibeAgendaDia?ano=" + ano + "&mes=" 
								+ (mes+1) + "&dia=" + dia + "'>" + dia + "</a></td>\n");
					} else {// caso contrário, exibe apenas o dia
						html.append("\t<td>" + dia + "</td>\n");
					}
					dia++;
				} else {
					html.append("<td>&nbsp;</td>\n");
				}
				aindaExistemDias = dia <= ultimoDiaMes;
			}
			html.append("</tr>\n");
		}
		html.append("</table>");
		
		// Retorna o HTML final da agenda
		return html.toString();
	}//FIM método getHTMLAgenda


}//FIM classe AgendaMensal
